<?php

	// PASTT: PHP Android Translation Tool
	// http://code.google.com/p/android-php-translator/
	// Licensed Apache License 2.0
	// http://www.apache.org/licenses/LICENSE-2.0
	
	define('DIRECT_ACCESSIBLE', TRUE);
	include('includes/common.php');
	
	if (!isset($_GET['lang'])) {
		die('No language specified; this should be in the query string.');
	}
	$lang = addslashes(htmlspecialchars(strip_tags($_GET['lang'])));
	if(isset($_GET['region'])) {
		$region = addslashes(htmlspecialchars(strip_tags($_GET['region'])));
		if (strlen($region) > 0) {
			$lang .= '-r' . strtoupper($region);
		}
	}
	if (preg_match('/^[a-z][a-z](-r[A-Z][A-Z])?$/', $lang) == 0) {
		die($lang . ' is not a valid language/locale code; should either be two letters (e.g. nl) or two letters dash two capitals (e.g. pt-rBR)');
	}
	$langname = $iso639[substr($lang, 0, 2)];
	
	// Get the last translation file, if it exists
	if ($transdir = @opendir($basedir . '/values-' . $lang)) {
	
		while (false !== ($stringsfile = readdir($transdir))) {
			// If it is a strings XML file, save it in the array
			if (substr($stringsfile, 0, 8) == 'strings.') {
				$existingfiles[] = $stringsfile;
			}
		}
		closedir($transdir);
		
		// Fiels should have been found here
		if (!isset($existingfiles) || count($existingfiles) <= 0) {
			die ('Every resource directory \'values-{lang}\' should at least have a single translation file.');
		}
		
		// Sort the list of all strings[.timestamp].xml files
		rsort($existingfiles);
		// Use the newest custom translation or strings.xml as a fallback
		$newesttranslation = $existingfiles[0];
		if ($newesttranslation == 'strings.xml' && count($existingfiles) > 1) {
			$newesttranslation = $existingfiles[1];
		}
		
	}
	
	// Save the updated translation?
	if (isset($_POST['submit'])) {
	
		// Traverse through the lines of the original strings file
		$lines = file($basedir . '/values/strings.xml');
		$outfile = "";
		$multiline = "";
		
		$skipElement = false;
		
		foreach ($lines as $line) {
			
			// <string> lines
			$line = trim($line);
			if (substr(trim($line), 0, 8) == '<string ' && substr($line, -9) == '</string>') {
				$namePos = strpos($line, 'name="') + 6;
				$stringPos = strPos($line, '>', $namePos) + 1;
				$name = substr($line, $namePos, strpos($line, '"', $namePos) - $namePos);
				//$newValue = stripslashes($_POST[$name]);
				
				$forceNoTranslationResult = array_search($name, $tagsForceNoTranslation);
				if ($forceNoTranslationResult != '' || ($excludeTagsWithSuffix && endsWith($name, $excludeTagsSuffix)) || ($excludeTagsWithPrefix && startsWith($name, $excludeTagsPrefix))) {	
					$skipElement = true;
				} else {
					$skipElement = false;
					$newValue = str_replace("\n","\\n",$_POST[$name]);
					if (trim($newValue) != '') {
						$outfile .= "\t" . substr($line, 0, $stringPos) . $newValue . substr($line, strrpos($line, '<')) . "\n";
					}
				}
				$multiline = "";
				
			} else if (substr(trim($line), 0, 8) == '<string ') {
				// Support multi line strings
				$multiline = "\t" . $line;
			
			} else if (substr($line, -9) == '</string>') {
				$multiline .= $line;
				$namePos = strpos($multiline, 'name="') + 6;
				$stringPos = strPos($multiline, '>', $namePos) + 1;
				$name = substr($multiline, $namePos, strpos($multiline, '"', $namePos) - $namePos);
				$newValue = str_replace("\n","\\n",stripslashes($_POST[$name]));
				if (trim($newValue) != '') {
					$outfile .= substr($multiline, 0, $stringPos) . $newValue . substr($multiline, strrpos($multiline, '<')) . "\n";
				}
				$multiline = "";
			// <string-array> lines
			} else if (substr($line, 0, 13) == '<string-array') {
				$namePos = strpos($line, 'name="') + 6;
				$name = substr($line, $namePos, strpos($line, '"', $namePos) - $namePos);
				
				$forceNoTranslationResult = array_search($name, $tagsForceNoTranslation);
				if ($forceNoTranslationResult != '' || ($excludeTagsWithSuffix && endsWith($name, $excludeTagsSuffix)) || ($excludeTagsWithPrefix && startsWith($name, $excludeTagsPrefix))) {	
					$skipElement = true;
				} else {
					$skipElement = false;
					$newValues = explode($arraySeparator, str_replace("\n","\\n",stripslashes($_POST[$name])));
					
					if (sizeof($newValues) == 0 || (sizeof($newValues) == 1 && $newValues[0] == '')) {
						$skipElement = true;
					} else {
						$n = 0;
						$outfile .= "\t" . $line . "\n";
						$multiline = "";
					}
				}
			// <item> lines
			} else if (substr($line, 0, 6) == '<item>') {
				if (!$skipElement) {
					$outfile .= "\t\t" . substr($line, 0, 6) . $newValues[$n] . substr($line, strrpos($line, '<')) . "\n";
					$n++;
					$multiline = "";
				}
			// </string-array> closing tag
			} else if (substr(trim($line), 0, 15) == '</string-array>') {
				if (!$skipElement) {
					$outfile .= "\t" . $line . "\n";
				}
			// Comments
			} else if (substr(trim($line), 0, 4) == '<!--') {
				$outfile .= "\t" . $line . "\n";
			// File opening tag
			} else if (substr(trim($line), 0, 11) == '<resources>') {				
				if (isset($_POST['pastt_translator_name'])) {
					$byname = htmlspecialchars(strip_tags($_POST['pastt_translator_name']));
					$byemail = htmlspecialchars(strip_tags($_POST['pastt_translator_email']));
				}
				
				$currentTime = date('d-m-Y H:i:s');
				$outfile .= "<!-- Last updated " . (isset($byname)? "by $byname ($byemail) " : "") . " at $currentTime" . " -->\n";
				$outfile .= $line . "\n";
			// File closing tag
			} else if (substr(trim($line), 0, 12) == '</resources>') {
				$outfile .= $line . "\n";
			} else {
				if (!$skipElement) {	
					if ($multiline != "") {
						$multiline .= $line;
					} else {
						$outfile .= $line . "\n";
					}
				}
			}
		}
				
		// Save the new translation with a new unique number (to prevent incorrect overwriting)
		$newfilename = 'strings.' . time() . '.xml';
		$basefilename = 'strings.xml';
		if (!is_dir($basedir . '/values-' . $lang)) {
			mkdir($basedir . '/values-' . $lang);
		}
		$filepath = 'values-' . $lang . '/' . $newfilename;
		$newfilepath = $basedir . '/' . $filepath;
		$basefilepath = 'values-' . $lang . '/' . $basefilename;
		$newbasefilepath = $basedir . '/' . $basefilepath;
		$mailfilepath = $application_url . '/res/' . $basefilepath;
		file_put_contents($newfilepath, $outfile);
		file_put_contents($newbasefilepath, $outfile);
		$newesttranslation = $newfilename;
		
		// Send an e-mail to notify of the new translation
		if (isset($sendmail) && $sendmail != "") {
			$newfilepathmail = $_SERVER['SERVER_ADDR'] ."/" . $_SERVER['REQUEST_URI'] . $filepath;
			
			if (isset($_POST['pastt_translator_name'])) {
				$byname = htmlspecialchars(strip_tags($_POST['pastt_translator_name']));
				$byemail = htmlspecialchars(strip_tags($_POST['pastt_translator_email']));
			}
			
			# Anti-header-injection
			# By Victor Benincasa <vbenincasa(AT)gmail.com>
			foreach($_REQUEST as $fields => $value) if(@eregi("TO:", $value) || @eregi("CC:", $value) || 
				@eregi("CCO:", $value) || @eregi("Content-Type", $value)) exit("ERROR: Code injection attempt denied! " .
				"Please don't use the following sequences in your message: 'TO:', 'CC:', 'CCO:' or 'Content-Type'.");

			mail(
				$sendmail,
				"$langname ($lang) translation updated for app " . $appname,
				"The $langname ($lang) translation of your Android string resource file " . 
				"has been updated." . (isset($byname)? "\n\nTranslator: $byname ($byemail)": "") . 
				"\n\nApplication: " . $appname .
				"\n\nThe new file was stored at $mailfilepath",
				(isset($frommail) && $frommail == '')? null: "From: $frommail");
				
		}
		
	}
	
	$pageTitle = 'Editing ' . $langname . ' translation - ' . $appname;
	include('includes/header.php');
	
	echo '<h1> <a href="./">' .$appname . '</a> >>> Translating to ' . $langname . ' (' . $lang . ')</h1>';
	
	function parseStrings($file) {
	    if (!file_exists($file)) {
	    	return;
	    }
		$lines = file($file);
		$multiline = "";
		foreach ($lines as $line) {
			
			// Empty lines
			$line = trim($line);
			if ($line == '') {
				//$out[]['type'] = 'empty';
				
			// <string> lines
			} else if (substr($line, 0, 8) == '<string ' && substr($line, -9) == '</string>') {
				$out[]['type'] = 'string';
				$namePos = strpos($line, 'name="') + 6;
				$stringPos = strPos($line, '>', $namePos) + 1;
				$name = substr($line, $namePos, strpos($line, '"', $namePos) - $namePos);
				$string = substr($line, $stringPos, strrpos($line, '<') - $stringPos);
				$out[count($out)-1]['name'] = $name;
				$out[count($out)-1]['value'] = $string;
				$multiline = "";
				
			} else if ((substr(trim($line), 0, 8) == '<string ') && ($multiline == "")) {
				// Support multi line strings
				$multiline = $line;
			
			} else if (substr($line, -9) == '</string>') {
				$multiline .= $line;
				$out[]['type'] = 'string';
				$namePos = strpos($multiline, 'name="') + 6;
				$stringPos = strPos($multiline, '>', $namePos) + 1;
				$name = substr($multiline, $namePos, strpos($multiline, '"', $namePos) - $namePos);
				$string = substr($multiline, $stringPos, strrpos($multiline, '<') - $stringPos);
				$out[count($out)-1]['name'] = $name;
				$out[count($out)-1]['value'] = $string;
				$multiline = "";
				
			// <string-array> lines
			} else if (substr($line, 0, 13) == '<string-array') {
				$out[]['type'] = 'stringarray';
				$namePos = strpos($line, 'name="') + 6;
				$name = substr($line, $namePos, strpos($line, '"', $namePos) - $namePos);
				$out[count($out)-1]['name'] = $name;
				$multiline = "";
				
			// <item> lines
			} else if (substr($line, 0, 6) == '<item>') {
				$val = substr($line, 6, strrpos($line, '<') - 6);
				$out[count($out)-1]['values'][] = $val;
				$multiline = "";
				
			} else if ($multiline != ""){
				$multiline .= $line;
			}
		}
		return $out;
	}
	
	function findTranslation($translations, $name) {
		foreach ($translations as $translation) {
			if ($translation['name'] == $name) {
				return $translation;
			}
		}
	}
	
	function dp($in) {
		echo '<pre>';
		print_r($in);
		echo '</pre><br />';
	}
	
	function endsWith($haystack, $needle) {
    	$length = strlen($needle);
	    if ($length == 0) {
	        return true;
    	}
    	return (substr($haystack, -$length) === $needle);
	}
	
	function startsWith($haystack, $needle) {
	    return !strncmp($haystack, $needle, strlen($needle));
	}
	
	// Load the XML files
	$strings = parseStrings($basedir . '/values/strings.xml');
	$stringsOld = parseStrings($basedir . '/values/strings.old.xml');
	//dp($strings);
	
	// Load the translation XML file, if it exists
	if (isset($newesttranslation)) {
		echo '
	<p>You are working with the last-saved translation \'' . $newesttranslation . '\' (saved ' . date('d F Y H:i', filemtime($basedir . '/values-' . $lang . '/' . $newesttranslation)) . '). When you save your updates it will not override it but make a new copy.</p>
	
	<p>
		Tips:<br/>
		<ul>
			<li>The greyed-out fields are marked as not to be translated.</li>
			<li>English values that are marked <font color=red><b>red and bold</b></font> have changed compared to the previous version, you should update your translation for them.</li>
			<li>Use the button in the upper-right corner "Show only missing translations" to hide the translations that are already filled in.<br/><b>CAUTION: This will hide the red-marked translation that should be reviewed!</b></li>
		</ul>
	</p>
	
	<p id="showmissingrow"><input type="button" id="showmissing" name="showmissing" value="Show only missing translations" onclick="javascript:flipShowOnlyMissing();" /></p>';
		$translations = parseStrings($basedir . '/values-' . $lang . '/' . $newesttranslation);
	} else {
		echo '
	<p>No translation for this language currently exists. When saving for the first time, it will create a directory and the first strings.{timestamp}.xml for this new language.</p>';
	}
	
	echo '
	<form id="translationform" name="translationform" method="post" action="translation.php?lang=' . $lang . '">
	<table id="translationtable">
		<tr>
			<th id="key">Key</th>
			<th id="org">English</th>
			<th id="trans">' . $langname . ' (' . $lang . ')</th>
		</tr>';
	
	$isuneven = false;
	$classuneven = ' class="uneven"';
	
	function encodeForHtml($in) {
		return htmlspecialchars($in);
	}
	function encodeForInput($in) {
		return str_replace(array('&','"'), array('&amp;','&quot;'), $in);
	}
	
	function array_search2d($needle, $haystack) {
	    for ($i = 0, $l = count($haystack); $i < $l; ++$i) {
    	    if ($needle == $haystack[$i]) return $i;
	    }
    	return -1;
	}
	
	// For every string in the original (English) file
	foreach ($strings as $string) {
		$name = $string['name'];
		$transtext = '';
		$disabled = '';
		$originalValueChanged = FALSE;
		$stringArray = false;
		
		$forceNoTranslationResult = array_search($name, $tagsForceNoTranslation);
		if ($forceNoTranslationResult != '' || ($excludeTagsWithSuffix && endsWith($name, $excludeTagsSuffix)) || ($excludeTagsWithPrefix && startsWith($name, $excludeTagsPrefix))) {
			$disabled = 'disabled="disabled"';
		}
		
		if ($string['type'] == 'string') {
			$value = $string['value'];
			if (isset($translations)) {
				$trans = findTranslation($translations, $name);
				$transtext = $trans['value'];
			}
			
			if (sizeof($stringsOld) > 0) {
				foreach ($stringsOld as $stringOld) {
					$nameOld = $stringOld['name'];
					if ($stringOld['type'] == 'string') {
						$valueOld = $stringOld['value'];
						if ($nameOld == $name && $valueOld != $value) {
							$originalValueChanged = TRUE;
							break;
						}
					}
				}
			}
		} else if ($string['type'] == 'stringarray') {
			$stringArray = true;
			$values = $string['values'];
			$value = implode($arraySeparator, $string['values']);
			
			if (isset($translations)) {
				$trans = findTranslation($translations, $name);
				
				if (sizeof($trans) != 0) {
					$transtext = implode($arraySeparator, $trans['values']);
				}
			}
			
			if (sizeof($stringsOld) > 0) {
				foreach ($stringsOld as $stringOld) {
					$nameOld = $stringOld['name'];
					if ($stringOld['type'] == 'stringarray') {
						$valueOld = implode($arraySeparator, $stringOld['values']);
						if ($nameOld == $name && $valueOld != $value) {
							$originalValueChanged = TRUE;
							break;
						}
					}
				}
			}
		}
		
		if ($disabled != '') {
			$transtext = $value;
		}
		
		//dp($trans);

		// Show a table row that has the key, the original English text and a input box with the translation text that is editable
		echo '
		<tr' . ($isuneven? $classuneven: '') . '>
			<td>' . $name . '</td>';
			
			if ($stringArray) {
				# echo '<td style="font-size:14px;">' . (($originalValueChanged && $disabled == '')?'<font color="red"><b>':'') .  str_replace("\\n","<br/>",encodeForHtml($value)) . ($originalValueChanged?'</b></font>':'') . '<br/>&nbsp;</td>';
				
				echo '<td style="font-size:14px;">';
				
				foreach ($values as $value) {
					echo '<input disabled type="text" value="' . encodeForHtml($value) . '" style="background: transparent; ' . (($originalValueChanged && $disabled == '')? 'color:red; font-weight:bold;' : 'color:black;') . '"/>';
				}
				echo '</td>';
				
				echo '<td>';
				echo '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . $transtext . '"/>';
				foreach ($values as $value) {
					$inputValue = '';
					if (isset($translations) && $disabled == '') {
						$inputValue = $trans['values'][array_search2d($value, $values)];
					} else if ($disabled != '') {
						$inputValue = $value;
					}
					$elementId = $name . '_' . array_search2d($value, $values);
					echo '<input ' . $disabled . ' type="text" id="' . $elementId . '" value="' . encodeForInput($inputValue) . '" onchange="storeArrayStringAdapter(this, \'' . $arraySeparator . '\')" style="color:black;"/>';
				}
				echo '</td>';
				$stringArray = false;
			} else {
				echo '<td style="font-size:14px;">' . (($originalValueChanged && $disabled == '')?'<font color="red"><b>':'') .  str_replace("\\n","<br/>",encodeForHtml($value)) . ($originalValueChanged?'</b></font>':'') . '<br/>&nbsp;</td>';
				echo '<td>';
				if (strpos(encodeForInput($value),"\\n") !== FALSE) echo '<textarea ' . $disabled . ' style="word-wrap: break-word;height:100%;width:100%;font-size:12px;" id="' . $name . '" name="' . $name . '">' . str_replace("\\n","\n",encodeForInput($transtext)) . '</textarea>';
				else echo '<input ' . $disabled . ' style="word-wrap: break-word;" type="text" id="' . $name . '" name="' . $name . '" value="' . encodeForInput($transtext) . '"/>';
				echo '</td>';
			}
		echo '</tr>';
		
		$isuneven = !$isuneven;
		
	}
	
	if ($askforemail) {
		echo '
		<tr>
			<td colspan="3">
				<h2>Submit your changes</h2>
			</td>
		</tr>
		<tr>
			<td colspan="3">Please fill in your name and e-mail address:</td>
		</tr>
		<tr>
			<td>Name:</td>
			<td colspan="2"><input type="input" id="pastt_translator_name" name="pastt_translator_name" value="" /></td>
		</tr>
		<tr>
			<td>E-mail:</td>
			<td colspan="2"><input type="input" id="pastt_translator_email" name="pastt_translator_email" value="" /></td>
		</tr>';
	}
	
	echo '
		<tr>
			<td colspan="3"><input type="submit" id="submit" name="submit" value="Save updated translation"';
			
			if ($askforemail) {
				echo ' onClick="return validateSubmitInput()" ';
			}
			
			echo '/></td>
		</tr>
		<tr>
			<td colspan="3" style="text-align: center;"><a href="./">or go back without saving</a></td>
		</tr>
	</table>
	</form>';
	
	include('includes/footer.php');

?>

